/* 
 * File:   tests.c
 * Author: Jonathan
 *
 * Created on 17 May 2014, 10:59
 */

#include <stdio.h>
#include <stdlib.h>
#include<assert.h>
#include "matmul.h"
#include "test_utilities.h"
#include "useful_macros.h"

#define N_SIZE 3
#define	M_SIZE 4
#define	O_SIZE 5
#define	THREADS 2 //=>tileSize=3

void printOutput(Mat matA, Mat matB, Mat matC, int N, int M, int O);


static int N = N_SIZE;
static int M = M_SIZE;
static int O = O_SIZE;
static int threadNum = THREADS;
  

int _myRoof(double value) {
	int roofVal, floorVal = value;
	if (value > (double) floorVal) {
		roofVal = floorVal + 1;
	} else {
		roofVal = floorVal;
        }
       // if (roofVal == 0)
         //   roofVal = 1;
	return roofVal;
}

void printJob(Job job){
    printf("Block A: offset=(%d,%d), size=(%d,%d) x Block B offset=(%d,%d), size=(%d,%d)\n",
            job.N_Offset, job.M_Offset, 
            job.dimentions.n, job.dimentions.m,
            job.M_Offset, job.O_Offset,
            job.dimentions.m, job.dimentions.o);
    return;
}

void printJobQueue(Queue *jobQueue){
    int i = 0;
    for (;i < (*jobQueue)->size; ++i){
        printf("Job no. %d, ", i);
        printJob((*jobQueue)->jobs[i]);
    }
    return;
}

bool testDivideToJobs(){
	Queue jobQueue = NULL;
	//create queue (with lock)
        int tileSize = (N/threadNum > 0)? (N/threadNum) : 1;
        int numberOfJobs = _myRoof((double)N/tileSize) * _myRoof((double)M/tileSize)
                                                        * _myRoof((double)O/tileSize);
        printf("pre-calculated number of jobs: %d\n", numberOfJobs);
        jobQueue = malloc(sizeof(Queue));
	jobQueue->jobs = malloc(numberOfJobs * sizeof(Job));
        jobQueue->size = numberOfJobs;
	jobQueue->iterator = 0;
	
	divideToJobs(N, M, O, threadNum, jobQueue);
        ASSERT_EQUAL(jobQueue->size, numberOfJobs);
        ASSERT_EQUAL(jobQueue->iterator, jobQueue->size);
        printJobQueue(&jobQueue);
        
        return true;
}


bool testThreadRun(){
    return true;
}


bool testDoJob(){
    Mat matA, matB, matC;
    _allocMatrix(&matA, N, M);
    _allocMatrix(&matB, M, O);
    _allocMatrix(&matC, N, O);
    
    _initToZeros(matA, N, M);
    _initToZeros(matB, M, O);
    _initToZeros(matC, N, O);
    
    printOutput(matA, matB, matC, N, M, O);
    
    Job job;
    Dimentions dim;
    
    dim.n=N;
    dim.m=M;
    dim.o=O;
    job.M_Offset = 0;
    job.N_Offset = 0;
    job.O_Offset = 0;
    job.dimentions = dim;
            
    doJob(job, matA, matB, matC, 0);

    free(matA);
    free(matB);
    free(matC);
    return true;
}
/* MAIN FUNCTION - CALLS TESTER FUNCTIONS */
    

int _main () {        

	RUN_TEST(testDivideToJobs);    
	RUN_TEST(testDoJob);    

	return 0;
}

